/**************************************************************************************************
 * red library                                                                                    *
 * Copyright © 2012 David Kretzmer                                                                *
 *                                                                                                *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software  *
 * and associated documentation files (the "Software"), to deal in the Software without           *
 * restriction,including without limitation the rights to use, copy, modify, merge, publish,      *
 * distribute,sublicense, and/or sell copies of the Software, and to permit persons to whom the   *
 * Software is furnished to do so, subject to the following conditions:                           *
 *                                                                                                *
 * The above copyright notice and this permission notice shall be included in all copies or       *
 * substantial portions of the Software.                                                          *
 *                                                                                                *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING  *
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND     *
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.        *
 *                                                                                                *
 *************************************************************************************************/

#pragma once

#include "red/static_matrix_base.hpp"


namespace red
{
	//=============================================================================================
	// Static column-major matrix
	//=============================================================================================
	template<typename Column, size_t Columns>
	class static_matrix : public static_matrix_base<static_matrix<Column, Columns>,
	                                                Column, Columns>
	{
	public:
		typedef static_matrix_base<static_matrix<Column, Columns>, Column, Columns> base_type;
		typedef typename base_type::column_type column_type;

		static size_t const columns = base_type::columns;
		static size_t const rows = base_type::rows;
		static size_t const elements = columns * rows;

		static bool const is_static = true;

		// Constructor
		static_matrix() = default;

		// Element access
		column_type const& element_at(size_t index) const
		{
			assert(index < columns);
			return m_columns[index];
		}

		column_type& element_at(size_t index)
		{
			assert(index < columns);
			return m_columns[index];
		}

		void resize(size_t size) { assert(size == elements); }

	private:
		column_type m_columns[columns];
	};


	//=============================================================================================
	// Fixed-size matrix traits
	//=============================================================================================
	template<typename Column, size_t Columns>
	struct is_matrix<static_matrix<Column, Columns> >
	{
		static bool const value = true;
	};


	//=============================================================================================
	// Types
	//=============================================================================================
	template<typename Real, size_t Dim>
	class static_vector;

	typedef static_matrix<static_vector<float, 3>, 3> matrix3x3f;
	typedef static_matrix<static_vector<float, 4>, 4> matrix4x4f;

} // namespace: red
